print("------------ 属性要求 ------------")
// protocol someProtocol {
//     var mustBeSettable: Int { get set }
//     var doesNotNeedToBeSettable: Int { get }
// }

protocol FullNamed {
    var fullNamed: String { get set }
}

// 提供fullNamed存储属性可满足协议
struct Person: FullNamed {
    var fullNamed: String
}
let john = Person(fullNamed: "John Appleseed")


class StarShip: FullNamed {
    var prefix: String?
    var name: String
    init(name: String, prefix: String? = nil) {
        self.name = name
        self.prefix = prefix
    }
    var fullNamed: String {
        get {
            return (prefix != nil ? prefix! + " " : " ") + name
        }
        set {
            print("newValue: \(newValue)")
            print(fullNamed)
        }
    }
}

var newPerson = StarShip(name: "EnterPrise", prefix: "USS")
newPerson.fullNamed = "Felix"
print(newPerson)
print(newPerson.name)
print(newPerson.fullNamed)

print("------------ 方法要求/静态方法要求 ------------")
protocol Animal {
    func eat(food: String)
    static func run(speed: Int)
}

class Dog: Animal {
    static func run(speed: Int) {
        print("static Dog run \(speed)")
    }
    
    func eat(food: String) {
        print("dog eat \(food)")
    }
}
Dog.run(speed: 70)
var d = Dog()
d.eat(food: "shit")

print("------------ 初始化器要求 ------------")
// 协议声明参考方法要求
// 实现需要添加required 如果是子类那么就要添加override关键字
protocol InitProtocol {
    init(brand: String)
}
class Car: InitProtocol {
    required init(brand: String) {
        print("\(brand)")
    }
}

print("------------ 协议可以作为类型 ------------")
func protocolMethod(animal: Animal) {
    animal.eat(food: "big shit")
}
protocolMethod(animal: d)

print("------------ 协议继承 ------------")
protocol InheritingProtocol: Animal, FullNamed {}

print("------------ 类专用协议 ------------")
protocol ObjectProtocol: AnyObject, Animal, FullNamed {}

print("------------ 协议组合 ------------")
func protocolTogether(animal: Animal & FullNamed) {
    animal.eat(food: "big shit")
}

print("------------ 可选协议要求 ------------")
// 使用optional修饰, 必须使用@objc标志标记, 只能被objc类唢呐, 不能被枚举和结构体采纳
